#ifndef EXPERIMENTUI_H
#define EXPERIMENTUI_H

#include <QWidget>
#include <tuple>
#include <QMainWindow>
#include <QListView>
#include <QFileDialog>
#include <QString>
#include <QDebug>
#include <QtCharts>
#include <QTimer>
#include <QDebug>
#include <QSpacerItem>
#include <QList>
#include <QScrollArea>
#include <QMenu>
#include <QVariant>
#include <QDateTime>
#include <QVBoxLayout>
#include <QRegExp>

#include "samplelibraryui.h"
#include "dyelibraryui.h"
#include "devicemanagementui.h"
#include "preference.h"
#include "pause.h"
#include "QPCR.h"
#include "QPCRDB.h"
#include "PreferencesService.h"
#include "ExperimentService.h"
#include "ProcedureService.h"
#include "TargetService.h"
#include "global.h"
#include "ui_stagestep.h"
#include "stagestep.h"
#include "Convertion.h"
#include "UiStruct.h"
#include "devicemanagementui.h"
#include "WLKService.h"
#include "ExportFileService.h"
#include "custommessagebox.h"
#include "analysisconfig.h"

#include "experimentpropertyui.h"
#include "experimentmethodui.h"
#include "experimentplateui.h"
#include "experimentrunui.h"
#include "experimentresultui.h"
#include "experimentexportui.h"

#define SHORT_SLEEP 5

namespace Ui {
class ExperimentUi;
}

class ExperimentUi : public QWidget
{
    Q_OBJECT

private:
    Ui::ExperimentUi *ui;

public:
    explicit ExperimentUi(QWidget *parent = nullptr);
    ~ExperimentUi();

signals:
    void renderAllExperimentsDeviceList();
    void uiSaveWlk(WLKData wlkData);
    void uiSaveAsWlk(WLKData wlkData);
    void updateActiveDeviceList();
    void changeHomePageTabName(QString experimentName);
    void renderRestoreList();
    void sigShowRunningStatus(QString status); // 渲染运行状态颜色到tab页上
    void mountPage(); // 挂载页面
    void closePage();

public slots:
    void currentActiveChanged(int index);
    void forceSaveWlkData();
    void mountPageInfos(); // 初始化所有页面信息
    void slotExport(); // 导出槽函数
    void slotChildClosePage();

public:
    void analysisGetWlkData(WLKData wlkData, WLKService *wlk, QString completeFilePath);
    void closeActiveDevice();
    bool currentIsRunning();
    void getWlkData(WLKData wlkData, WLKService *wlk, QString completeFilePath);
    void renderActiveDevice();
    void saveWlkData();
    void saveAsWlkData();
    QString sendExperimentName();

    void syncExportInfo(); // 同步导出和配置文件
    void updateAnalysisConfig(QList<AnalysisTarget> alysTar); // 分析配置工具栏更新
    void setObjs(AnalysisConfig *alysCfg, PreferencesService *preference); // 设置对象
    QList<AnalysisTarget> getAnalysisTarget(); // 返回数据分析靶基因

    void mountPageFunc(); // 挂载函数

    QString returnCurTabWlkName(); // 返回当前wlk文件名

public:
    bool isImport; // 判断是否为导入的实验数据
    QString completeFilePath; // 完整保存文件路径
    ExperimentRunUi *experimentRunUi;
    int thisExpIndex; // 存储当前实验下标
    PreferencesService *preferencesService; // 偏好设置服务类

private:
    ExperimentPropertyUi *experimentPropertyUi;
    ExperimentMethodUi *experimentMethodUi;
    ExperimentPlateUi *experimentPlateUi;
    ExperimentResultUi *experimentResultUi;
    ExperimentExportUi *experimentExportUi;

    ExportFileService *exportFileService;
    ExperimentService *experimentService;
    CustomMessageBox *cusMsg;
    int cycling;
    int nextFlag[6]= {0, 0, 0, 0, 0, 0};  // 六个 flag，用来记录点击下一步的次数
    int volumn;
    ProcedureService *procedureService;
    QVBoxLayout *expPropetyLayout;
    QVBoxLayout *expMethodLayout;
    QVBoxLayout *expPlateLayout;
    QVBoxLayout *expRunLayout;
    QVBoxLayout *expResultLayout;
    QVBoxLayout *expExportLayout;

    /* 半全局变量 */
    bool deviceExistence;
    Experiment experiment; // 实验属性信息
    int currentSelectedDeviceIndex; // 当前所选的设备下标
    int previousTabbarIndex; // 前一个页面的页面下标
    int procedureStepCount; // 扩增所有步骤
    int procedureStageCount; // 扩增所有阶段
    int totalrunningTime; // 总运行时间
    QHash<QHash<QString,QString>,QList<QHash<QString,QString>>> procedureList; // 扩增数据
    QHash<QString, QString> targetLegend; // 获取对应报告基因的靶基因
    QList<QList<QHash<QString, QString>>> saveYingguangDataList; // 荧光数据列表
    QList<YingGuang> saveYingguangList; // 保存荧光数据
    QString fPath; // 配置文件文件保存路径
    QString id; // 实验 id
    QVariant currentSelectedDevice; // 当前设备的 QVariant
    ReactionPlate reactionPlate; // 反应板信息
    WLKData wlkData; // wlk文件数据
    WLKService *wlk; // wlk服务类
    QList<QString> ct; // ct值

    QString canBi; // 参比荧光
    QList<AnalysisTarget> alysTar; // 分析配置靶基因

    QString wlkFileName; // wlk文件名

    /* 工具栏对象 */
    AnalysisConfig *alysCfg;

private:
    /* 数据对比(传入数据和所暂存数据对比) */
    bool contrastPropertyData(Experiment tExp); // 实验属性对比
    bool contrastMethodData(std::tuple<int, int, int, int, int> basicInfo, QHash<QHash<QString,QString>,QList<QHash<QString,QString>>> tProcedureList); // 扩增数据对比
    bool contrastReactionData(ReactionPlate tReaction); // 反应板数据对比

    void dataAnalysisJump2Result();
    bool contrastData();
    void backfillWlkDataDevice(QString wlkDeviceName);
    void dataAnalysis();
    void methodToPlate(int volumn, int procedureStepCount, int procedureStageCount, int totalrunningTime);
    void propertyToMethod(Experiment experiment);
    void plateToRun();
    void renderWlkData();
    void resultToExport();
    void runningSave();
    void runToResult();
    void sleep(int msec);
    void updatePageInfos(int index, bool init); // 页面跳转，更新所有页面数据
    void runPlateToRun();
};

#endif // EXPERIMENTUI_H
